home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / EXAMPLES / oversphere.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  5.2 KB  |  211 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1996. */
  3.  
  4. /* This program is freely distributable without licensing fees 
  5.    and is provided without guarantee or warrantee expressed or 
  6.    implied. This program is -not- in the public domain. */
  7.  
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <GL/glut.h>
  11.  
  12. #define MAX_SPHERES 50
  13.  
  14. typedef struct {
  15.   GLfloat x, y, z;
  16.   int detail;
  17.   int material;
  18. } SphereInfo;
  19. /* *INDENT-OFF* */
  20.  
  21. GLfloat lightPos[4] = {2.0, 4.0, 2.0, 1.0};
  22. GLfloat lightDir[4] = {-2.0, -4.0, -2.0, 1.0};
  23. GLfloat lightAmb[4] = {0.2, 0.2, 0.2, 1.0};
  24. GLfloat lightDiff[4] = {0.8, 0.8, 0.8, 1.0};
  25. GLfloat lightSpec[4] = {0.4, 0.4, 0.4, 1.0};
  26. GLfloat matColor[3][4] = {
  27.   {0.5, 0.0, 0.0, 1.0},
  28.   {0.0, 0.5, 0.0, 1.0},
  29.   {0.0, 0.0, 0.5, 1.0},
  30. };
  31. /* *INDENT-ON* */
  32.  
  33. GLdouble modelMatrix[16], projMatrix[16];
  34. GLint viewport[4];
  35. int width, height;
  36. int opaque, transparent;
  37. SphereInfo sphereInfo[MAX_SPHERES];
  38. int spheres = 0;
  39. SphereInfo overlaySphere, oldOverlaySphere;
  40.  
  41. void
  42. drawSphere(SphereInfo * sphere)
  43. {
  44.   glPushMatrix();
  45.   glTranslatef(sphere->x, sphere->y, sphere->z);
  46.   glMaterialfv(GL_FRONT_AND_BACK,
  47.     GL_AMBIENT_AND_DIFFUSE, matColor[sphere->material]);
  48.   glutSolidSphere(1.0, sphere->detail, sphere->detail);
  49.   glPopMatrix();
  50. }
  51.  
  52. void
  53. display(void)
  54. {
  55.   int i;
  56.  
  57.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  58.   for (i = 0; i < spheres; i++) {
  59.     drawSphere(&sphereInfo[i]);
  60.   }
  61.   glutSwapBuffers();
  62. }
  63.  
  64. void
  65. overlayDisplay(void)
  66. {
  67.   if (glutLayerGet(GLUT_OVERLAY_DAMAGED)) {
  68.     /* If damaged, clear the overlay. */
  69.     glClear(GL_COLOR_BUFFER_BIT);
  70.   } else {
  71.     /* If not damaged, undraw last overlay sphere. */
  72.     glIndexi(transparent);
  73.     drawSphere(&oldOverlaySphere);
  74.   }
  75.   glIndexi(opaque);
  76.   drawSphere(&overlaySphere);
  77.   /* Single buffered window needs flush. */
  78.   glFlush();
  79.   /* Remember last overaly sphere position for undrawing. */
  80.   oldOverlaySphere = overlaySphere;
  81. }
  82.  
  83. void
  84. reshape(int w, int h)
  85. {
  86.   width = w;
  87.   height = h;
  88.   /* Reshape both layers. */
  89.   glutUseLayer(GLUT_OVERLAY);
  90.   glViewport(0, 0, w, h);
  91.   glutUseLayer(GLUT_NORMAL);
  92.   glViewport(0, 0, w, h);
  93.   /* Read back viewport for gluUnProject. */
  94.   glGetIntegerv(GL_VIEWPORT, viewport);
  95. }
  96.  
  97. void
  98. mouse(int button, int state, int x, int y)
  99. {
  100.   GLdouble objx, objy, objz;
  101.  
  102.   gluUnProject(x, height - y, 0.95,
  103.     modelMatrix, projMatrix, viewport,
  104.     &objx, &objy, &objz);
  105.   overlaySphere.x = objx;
  106.   overlaySphere.y = objy;
  107.   overlaySphere.z = objz;
  108.   overlaySphere.material = button;
  109.   glutUseLayer(GLUT_OVERLAY);
  110.   glutSetColor(opaque,
  111.     2 * matColor[button][0],  /* Red. */
  112.     2 * matColor[button][1],  /* Green. */
  113.     2 * matColor[button][2]);  /* Blue. */
  114.   if (state == GLUT_UP) {
  115.     glutHideOverlay();
  116.     if (spheres < MAX_SPHERES) {
  117.       sphereInfo[spheres] = overlaySphere;
  118.       sphereInfo[spheres].detail = 25;  /* Fine tesselation. */
  119.       spheres++;
  120.     } else {
  121.       printf("oversphere: Out of spheres.\n");
  122.     }
  123.     glutPostRedisplay();
  124.   } else {
  125.     overlaySphere.detail = 10;  /* Coarse tesselation. */
  126.     glutShowOverlay();
  127.     glutPostOverlayRedisplay();
  128.   }
  129. }
  130.  
  131. void
  132. motion(int x, int y)
  133. {
  134.   GLdouble objx, objy, objz;
  135.  
  136.   gluUnProject(x, height - y, 0.95,
  137.     modelMatrix, projMatrix, viewport,
  138.     &objx, &objy, &objz);
  139.   overlaySphere.x = objx;
  140.   overlaySphere.y = objy;
  141.   overlaySphere.z = objz;
  142.   glutPostOverlayRedisplay();
  143. }
  144.  
  145. void
  146. setupMatrices(void)
  147. {
  148.   glMatrixMode(GL_PROJECTION);
  149.   gluPerspective( /* degrees field of view */ 50.0,
  150.     /* aspect ratio */ 1.0, /* Z near */ 1.0, /* Z far */ 10.0);
  151.   glMatrixMode(GL_MODELVIEW);
  152.   gluLookAt(
  153.     0.0, 0.0, 5.0,      /* eye is at (0,0,5) */
  154.     0.0, 0.0, 0.0,      /* center is at (0,0,0) */
  155.     0.0, 1.0, 0.);      /* up is in positive Y direction */
  156. }
  157.  
  158. int
  159. main(int argc, char **argv)
  160. {
  161.   glutInitWindowSize(350, 350);
  162.   glutInit(&argc, argv);
  163.  
  164.   glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
  165.   glutCreateWindow("Overlay Sphere Positioning Demo");
  166.   glutDisplayFunc(display);
  167.   glutReshapeFunc(reshape);
  168.   glutMouseFunc(mouse);
  169.   glutMotionFunc(motion);
  170.  
  171.   glEnable(GL_DEPTH_TEST);
  172.   glEnable(GL_CULL_FACE);  /* Solid spheres benefit greatly
  173.                               from back face culling. */
  174.   setupMatrices();
  175.   /* Read back matrices for use by gluUnProject. */
  176.   glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
  177.   glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
  178.  
  179.   /* Set up lighting. */
  180.   glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
  181.   glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb);
  182.   glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiff);
  183.   glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpec);
  184.   glEnable(GL_LIGHT0);
  185.   glEnable(GL_LIGHTING);
  186.  
  187.   glutInitDisplayMode(GLUT_INDEX | GLUT_SINGLE);
  188.   if (glutLayerGet(GLUT_OVERLAY_POSSIBLE) == 0) {
  189.     printf("oversphere: no overlays supported; aborting.\n");
  190.     exit(1);
  191.   }
  192.   glutEstablishOverlay();
  193.   glutHideOverlay();
  194.   glutOverlayDisplayFunc(overlayDisplay);
  195.  
  196.   /* Find transparent and opaque index. */
  197.   transparent = glutLayerGet(GLUT_TRANSPARENT_INDEX);
  198.   opaque = (transparent + 1)
  199.     % glutGet(GLUT_WINDOW_COLORMAP_SIZE);
  200.  
  201.   /* Draw overlay sphere as an outline. */
  202.   glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  203.   /* Make sure overlay clears to transparent. */
  204.   glClearIndex(transparent);
  205.   /* Set up overlay matrices same as normal plane. */
  206.   setupMatrices();
  207.  
  208.   glutMainLoop();
  209.   return 0;
  210. }
  211.